require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` }); // 加载环境变量

//引入依赖包
const createError = require("http-errors");
const express = require("express");
const fs = require("fs");
const path = require("path");
const cookieParser = require("cookie-parser");
const morgan = require("morgan");
const logger = require("./logger");

const app = express();

app.use(morgan("dev")); // 使用 morgan打印请求日志
app.use(express.json()); // 解析请求体
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
app.use("/uploads", express.static(path.join(__dirname, "uploads")));

const { expressjwt } = require("express-jwt");

app.use(
    expressjwt({
        credentialsRequired: true,
        secret: process.env.SECRET_KEY,
        algorithms: ["HS256"],
        getToken: (req) => {
            if (!req.headers.authorization) {
                throw new Error("请求头没有携带token");
            } else {
                return req.headers.authorization;
            }
        },
    }).unless({
        path: ["/auth/login", "/auth/register"],
    })
);

// 动态挂载路由的函数
function mountRoutes() {
    const routesDir = path.join(__dirname, "routes");

    fs.readdirSync(routesDir).forEach((file) => {
        if (file.endsWith(".js")) {
            const route = require(path.join(routesDir, file));
            const moduleName = file.split(".")[0];
            app.use(`/${moduleName}`, route);
        }
    });
}
mountRoutes();

// 捕捉404错误
app.use(function (req, res, next) {
    next(createError(404));
});

app.use((err, req, res, next) => {
    logger.error(`${req.method} ${req.originalUrl} ` + err.message); //捕获到错误输入log日志

    if (err.name === "UnauthorizedError") {
        return res.status(401).json({
            code: 401,
            message: "token验证失败",
        });
    }

    if (err.status === 404) {
        return res.status(404).json({
            code: 404,
            message: "请求路径不存在",
        });
    }

    return res.status(err.status || 200).json({
        code: err.status || 200,
        message: err.message,
    });
});

module.exports = app;
